%% Author: John 
%% Created: 2010-6-28
%% Description: TODO: Add description to tcp_server
-module(tcp_server).

%%
%% Include files
%%

%%
%% Exported Functions
%%
-export([nano_client_eval/1, start_nano_server/0,start_seq_server/0,start_parallel_server/0,start_server/0]).

%%
%% API Functions
%%

%%
%% TODO: Add description of nano_client_eval/function_arity
%%
nano_client_eval(Str) ->
    {ok,Socket}=gen_tcp:connect("localhost",2345,[binary,{packet,4}]),
    ok=gen_tcp:send(Socket,term_to_binary(Str)),
    receive
        {tcp,Socket,Bin} ->
            io:format("Client received binary = ~p~n",[Bin]),
            Val=binary_to_term(Bin),
            io:format("Client result = ~p~n",[Val]),
            gen_tcp:close(Socket)
    end.
%%
%% TODO: Add description of start_nano_server/function_arity
%%
start_nano_server() ->
    {ok,Listen}=gen_tcp:listen(2345,[binary,{packet,4},
                                            {reuseaddr,true},
                                            {active,true}]),
    {ok,Socket}=gen_tcp:accept(Listen),
    gen_tcp:close(Listen),
    loop(Socket).
%% 
%% seq server
%% 
start_seq_server() ->
    {ok,Listen} = gen_tcp:listen(2345,[binary,{packet,4},
                                            {reuseaddr,true},
                                            {active,true}]),
    seq_loop(Listen).

seq_loop(Listen) ->
    {ok,Socket} = gen_tcp:accept(Listen),
    loop(Socket),
    seq_loop(Listen).

%% 
%% parallel_server
%% 
start_parallel_server() ->
    {ok,Listen} = gen_tcp:listen(2345,[binary,{packet,4},
                                            {reuseaddr,true},
                                            {active,true}]),
    spawn(fun() -> par_connect(Listen) end).

par_connect(Listen) ->
    {ok,Socket} = gen_tcp:accept(Listen),
    spawn(fun() -> par_connect(Listen) end),
    loop(Socket).


%% good_server
start_server()->
	 {ok,Listen} = gen_tcp:listen(2345,[binary,{packet,4},{active,once}]),
	 {ok,Socket} = gen_tcp:accept(Listen),
	 loop2(Socket).



%%
%% Local Functions
%%
loop(Socket) ->
    receive
        {tcp,Socket,Bin} ->
            io:format("Server received binary = ~p~n",[Bin]),
            Str=binary_to_term(Bin),
            io:format("Server (unpacked) ~p~n",[Str]),
            Reply=lib_misc:string2value(Str),
            io:format("Server replying = ~p~n",[Reply]),
            gen_tcp:send(Socket,term_to_binary(Str)),
            loop(Socket);
        {tcp_closed,Socket} ->
            io:format("Server socket closed~n")
    end.


loop2(Socket) ->
    receive
        {tcp,Socket,Bin} ->
			io:format("Server received binary = ~p~n",[Bin]),
            Str=binary_to_term(Bin),
            io:format("Server (unpacked) ~p~n",[Str]),
            gen_tcp:send(Socket,term_to_binary(Str)),
            %%next msg
            inet:setopts(Socket,[{active,once}]),
            loop2(Socket);
        {tcp_closed,Socket} ->
            io:format("Server socket closed~n")
    end.
